using Domain.Entities;
using Domain.Misc;
using NHibernate;
using NHibernate.Expression;
using System.Collections.Generic;

namespace Domain.Services
{
    public static class CategoryService
    {
        /*****************************************************************************************
        * Getters
        * ***************************************************************************************/
        public static IList<Category> GetAll()
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            return session.CreateCriteria(typeof(Category)).AddOrder(Order.Asc("Index")).List<Category>();
        }

        public static Category GetById(byte categoryId)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            return session.Get<Category>(categoryId);
        }

        /*****************************************************************************************
        * Adders
        * ***************************************************************************************/
        public static Category NewCategory(string name)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                Category category = new Category();
                category.Name = name;
                category.Index = IndexedTools.NextIndex(GetAll());
                session.SaveOrUpdate(category);
                transaction.Commit();
                return category;
            }
        }

        /*****************************************************************************************
        * Updaters
        * ***************************************************************************************/
        public static void MoveCategoryUp(Category category)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                IList<Category> categories = GetAll();
                if (IndexedTools.MoveUp(category, categories))
                {
                    foreach (Category categoryToUpdate in categories)
                    {
                        session.SaveOrUpdate(categoryToUpdate);
                    }
                }
                transaction.Commit();
            }
        }

        public static void MoveCategoryDown(Category category)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                IList<Category> categories = GetAll();
                if (IndexedTools.MoveDown(category, categories))
                {
                    foreach (Category categoryToUpdate in categories)
                    {
                        session.SaveOrUpdate(categoryToUpdate);
                    }
                }
                transaction.Commit();
            }
        }

        public static void UpdateCategory(Category category, string name)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                category.Name = name;
                session.SaveOrUpdate(category);
                transaction.Commit();
            }
        }
        
        /*****************************************************************************************
        * Deleters
        * ***************************************************************************************/
        public static void RemoveCategory(Category category)
        {
            ISession session = NHibernateHelper.Instance.CurrentSession;
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Delete(category);
                transaction.Commit();
            }
        }
    }
}
